2 using System
.Collections
.Generic
;
4 using System
.Windows
.Forms
;
5 using System
.Runtime
.InteropServices
;
9 internal class ShellBrowserUpdater
: NativeWindow
13 private ShellBrowser br
;
14 private uint notifyId
= 0;
18 public ShellBrowserUpdater(ShellBrowser br
)
21 CreateHandle(new CreateParams());
23 ShellAPI
.SHChangeNotifyEntry entry
= new ShellAPI
.SHChangeNotifyEntry();
24 entry
.pIdl
= br
.DesktopItem
.PIDLRel
.Ptr
;
25 entry
.Recursively
= true;
27 notifyId
= ShellAPI
.SHChangeNotifyRegister(
29 ShellAPI
.SHCNRF
.InterruptLevel
| ShellAPI
.SHCNRF
.ShellLevel
,
30 ShellAPI
.SHCNE
.ALLEVENTS
| ShellAPI
.SHCNE
.INTERRUPT
,
31 ShellAPI
.WM
.SH_NOTIFY
,
33 new ShellAPI
.SHChangeNotifyEntry
[] { entry }
);
36 ~
ShellBrowserUpdater()
40 ShellAPI
.SHChangeNotifyDeregister(notifyId
);
41 GC
.SuppressFinalize(this);
45 protected override void WndProc(ref Message m
)
47 if (m
.Msg
== (int)ShellAPI
.WM
.SH_NOTIFY
)
49 ShellAPI
.SHNOTIFYSTRUCT shNotify
=
50 (ShellAPI
.SHNOTIFYSTRUCT
)Marshal
.PtrToStructure(m
.WParam
, typeof(ShellAPI
.SHNOTIFYSTRUCT
));
52 //Console.Out.WriteLine("Event: {0}", (ShellAPI.SHCNE)m.LParam);
53 //if (shNotify.dwItem1 != IntPtr.Zero)
54 //PIDL.Write(shNotify.dwItem1);
55 //if (shNotify.dwItem2 != IntPtr.Zero)
56 //PIDL.Write(shNotify.dwItem2);
58 switch ((ShellAPI
.SHCNE
)m
.LParam
)
62 case ShellAPI
.SHCNE
.CREATE
:
65 if (!PIDL
.IsEmpty(shNotify
.dwItem1
))
67 IntPtr parent
, child
, relative
;
68 PIDL
.SplitPidl(shNotify
.dwItem1
, out parent
, out child
);
70 PIDL parentPIDL
= new PIDL(parent
, false);
71 ShellItem parentItem
= br
.GetShellItem(parentPIDL
);
72 if (parentItem
!= null && parentItem
.FilesExpanded
&& !parentItem
.SubFiles
.Contains(child
))
74 ShellAPI
.SHGetRealIDL(
75 parentItem
.ShellFolder
,
78 parentItem
.AddItem(new ShellItem(br
, parentItem
, relative
));
81 Marshal
.FreeCoTaskMem(child
);
88 case ShellAPI
.SHCNE
.RENAMEITEM
:
91 if (!PIDL
.IsEmpty(shNotify
.dwItem1
) && !PIDL
.IsEmpty(shNotify
.dwItem2
))
93 ShellItem item
= br
.GetShellItem(new PIDL(shNotify
.dwItem1
, true));
95 item
.Update(shNotify
.dwItem2
, ShellItemUpdateType
.Renamed
);
101 case ShellAPI
.SHCNE
.DELETE
:
104 if (!PIDL
.IsEmpty(shNotify
.dwItem1
))
106 IntPtr parent
, child
;
107 PIDL
.SplitPidl(shNotify
.dwItem1
, out parent
, out child
);
109 PIDL parentPIDL
= new PIDL(parent
, false);
110 ShellItem parentItem
= br
.GetShellItem(parentPIDL
);
111 if (parentItem
!= null && parentItem
.SubFiles
.Contains(child
))
112 parentItem
.RemoveItem(parentItem
.SubFiles
[child
]);
114 Marshal
.FreeCoTaskMem(child
);
121 case ShellAPI
.SHCNE
.UPDATEITEM
:
124 if (!PIDL
.IsEmpty(shNotify
.dwItem1
))
126 ShellItem item
= br
.GetShellItem(new PIDL(shNotify
.dwItem1
, true));
129 Console
.Out
.WriteLine("Item: {0}", item
);
130 item
.Update(IntPtr
.Zero
, ShellItemUpdateType
.Updated
);
131 item
.Update(IntPtr
.Zero
, ShellItemUpdateType
.IconChange
);
140 #region Folder Changes
142 case ShellAPI
.SHCNE
.MKDIR
:
143 case ShellAPI
.SHCNE
.DRIVEADD
:
144 case ShellAPI
.SHCNE
.DRIVEADDGUI
:
145 #region Make Directory
147 if (!PIDL
.IsEmpty(shNotify
.dwItem1
))
149 IntPtr parent
, child
, relative
;
150 PIDL
.SplitPidl(shNotify
.dwItem1
, out parent
, out child
);
152 PIDL parentPIDL
= new PIDL(parent
, false);
153 ShellItem parentItem
= br
.GetShellItem(parentPIDL
);
154 if (parentItem
!= null && parentItem
.FoldersExpanded
&& !parentItem
.SubFolders
.Contains(child
))
156 ShellAPI
.SHGetRealIDL(
157 parentItem
.ShellFolder
,
161 IntPtr shellFolderPtr
;
162 if (parentItem
.ShellFolder
.BindToObject(
165 ref ShellAPI
.IID_IShellFolder
,
166 out shellFolderPtr
) == ShellAPI
.S_OK
)
168 parentItem
.AddItem(new ShellItem(br
, parentItem
, relative
, shellFolderPtr
));
171 Marshal
.FreeCoTaskMem(relative
);
174 Marshal
.FreeCoTaskMem(child
);
181 case ShellAPI
.SHCNE
.RENAMEFOLDER
:
182 #region Rename Directory
184 if (!PIDL
.IsEmpty(shNotify
.dwItem1
) && !PIDL
.IsEmpty(shNotify
.dwItem2
))
186 ShellItem item
= br
.GetShellItem(new PIDL(shNotify
.dwItem1
, false));
189 //Console.Out.WriteLine("Update: {0}", item);
190 item
.Update(shNotify
.dwItem2
, ShellItemUpdateType
.Renamed
);
197 case ShellAPI
.SHCNE
.RMDIR
:
198 case ShellAPI
.SHCNE
.DRIVEREMOVED
:
199 #region Remove Directory
201 if (!PIDL
.IsEmpty(shNotify
.dwItem1
))
203 IntPtr parent
, child
;
204 PIDL
.SplitPidl(shNotify
.dwItem1
, out parent
, out child
);
206 PIDL parentPIDL
= new PIDL(parent
, false);
207 ShellItem parentItem
= br
.GetShellItem(parentPIDL
);
208 if (parentItem
!= null && parentItem
.SubFolders
.Contains(child
))
209 parentItem
.RemoveItem(parentItem
.SubFolders
[child
]);
211 Marshal
.FreeCoTaskMem(child
);
218 case ShellAPI
.SHCNE
.UPDATEDIR
:
219 case ShellAPI
.SHCNE
.ATTRIBUTES
:
220 #region Update Directory
222 if (!PIDL
.IsEmpty(shNotify
.dwItem1
))
224 ShellItem item
= br
.GetShellItem(new PIDL(shNotify
.dwItem1
, true));
227 item
.Update(IntPtr
.Zero
, ShellItemUpdateType
.Updated
);
228 item
.Update(IntPtr
.Zero
, ShellItemUpdateType
.IconChange
);
235 case ShellAPI
.SHCNE
.MEDIAINSERTED
:
236 case ShellAPI
.SHCNE
.MEDIAREMOVED
:
239 if (!PIDL
.IsEmpty(shNotify
.dwItem1
))
241 ShellItem item
= br
.GetShellItem(new PIDL(shNotify
.dwItem1
, true));
243 item
.Update(IntPtr
.Zero
, ShellItemUpdateType
.MediaChange
);
251 #region Other Changes
253 case ShellAPI
.SHCNE
.ASSOCCHANGED
:
254 #region Update Images
261 case ShellAPI
.SHCNE
.NETSHARE
:
262 case ShellAPI
.SHCNE
.NETUNSHARE
:
265 case ShellAPI
.SHCNE
.UPDATEIMAGE
:
276 private void UpdateRecycleBin()
278 ShellItem recycleBin
= br
.DesktopItem
["Recycle Bin"];
279 if (recycleBin
!= null)
280 recycleBin
.Update(IntPtr
.Zero
, ShellItemUpdateType
.IconChange
);